package com.simple.service;

import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class YouDaoQuestion {


    //https://openapi.youdao.com/ocrquestionapi

    static String ID ="017f04f6211c822a";
    static String Key="BNbID8xnrm1LQ4ArXWJkUFqWfX91dFcC";



    public static String ocrquestionapi(String img) throws Exception {
        return ocrquestionapi(img, ID, Key);
    }


    public static String ocrquestionapi(String img,String appKey, String appSecret)
            throws Exception {
        long time = System.currentTimeMillis();
        Map<String, String> map = new HashMap<>();
        String url = "https://openapi.youdao.com/ocrquestionapi";
        //String appKey = ID;
        //String appSecret = Key;
        String salt = String.valueOf(System.currentTimeMillis());
        map.put("q", img);
        map.put("appKey", appKey);
        map.put("salt", salt);
        map.put("curtime", String.valueOf(System.currentTimeMillis() / 1000));
        String sign = encrypt(appKey + getInput(img) + salt + map.get("curtime") + appSecret, null);
        map.put("sign", sign);
        map.put("signType", "v2");
        map.put("type", "1");
        map.put("searchType", "img");


        String result = requestOCRForHttp(url, map);
        System.out.println(""+result);
        System.out.println("youdao ocrquestionapi="+(System.currentTimeMillis()-time)+"ms");
        return result;
    }


    private static String encrypt(String strSrc, String encName)
            throws NoSuchAlgorithmException {
//        Preconditions.checkNotNull(strSrc);
        byte[] bt = strSrc.getBytes();
        if (encName == null || "".equals(encName)) {
            encName = "SHA-256";
        }
        MessageDigest md = MessageDigest.getInstance(encName);
        md.update(bt);
        return bytes2Hex(md.digest());
    }

    private static String bytes2Hex(byte[] bts) {
        String des = "";
        String tmp = null;
        for (int i = 0; i < bts.length; i++) {
            tmp = (Integer.toHexString(bts[i] & 0xFF));
            if (tmp.length() == 1) {
                des += "0";
            }
            des += tmp;
        }
        return des;
    }


    /**
     * 获得图片base64的input
     * @param input
     * @return
     */
    private static String getInput(String input) {
        if (input == null)
            return null;
        String result = "";
        int len = input.length();
        if (len <= 20) {
            result = input;
        }
        else {
            String startStr = input.substring(0, 10);
            String endStr = input.substring(len - 10, len);
            result = startStr + len + endStr;
        }
        return result;
    }

    private static String requestOCRForHttp(String url, Map<String, String> requestParams)
            throws Exception {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        /** HttpPost */
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        Iterator<Map.Entry<String, String>> it = requestParams.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> en = it.next();
            String key = en.getKey();
            String value = en.getValue();
            if (value != null) {
                params.add(new BasicNameValuePair(key, value));
            }
        }
        httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
        /** HttpResponse */
        CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
        try {
            HttpEntity httpEntity = httpResponse.getEntity();
            result = EntityUtils.toString(httpEntity, "utf-8");
            EntityUtils.consume(httpEntity);
        }
        finally {
            try {
                if (httpResponse != null) {
                    httpResponse.close();
                }
            }
            catch (IOException e) {
                System.out.println("## release resouce error ##" + e);
            }
        }
        return result;
    }


    public static void main(String[] args) throws Exception {
        String imgBase64 = getImageStr( new File("D:\\2.OCR_TXT\\NO_S\\2.png"));


        System.out.println(ocrquestionapi(imgBase64));
    }


    private static String getImageStr(File imgFile) {// 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        InputStream in = null;
        byte[] data = null;
        // 读取图片字节数组
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if(in != null) {
                try {
                    in.close();
                }
                catch(Exception e) {

                }
            }
        }
        // 对字节数组Base64编码
        return Base64.encode(data);
    }
}
